{
int ret;
FILE *logfile = stdout;
-
- const struct sigaction act = { .sa_handler = close_handler };
+ struct sigaction act;
opts.outfile = 0;
opts.num_cpus = 1;
logfile = fopen(opts.outfile, "w");
/* ensure that if we get a signal, we'll do cleanup, then exit */
+ act.sa_handler = close_handler;
sigaction(SIGHUP, &act, 0);
sigaction(SIGTERM, &act, 0);
sigaction(SIGINT, &act, 0);
}
else if (strcmp(ptr, "fThreadInfo") == 0)
{
- struct task_struct *p = &idle0_task;
+ struct task_struct *p;
u_long flags;
int count = 0, buf_idx = 0;
read_lock_irqsave (&tasklist_lock, flags);
pdb_out_buffer[buf_idx++] = 'm';
- while ( (p = p->next_task) != &idle0_task )
+ for_each_domain ( p )
{
domid_t domain = p->domain + PDB_DOMAIN_OFFSET;
{
domid_t dom = op->u.destroydomain.domain;
int force = op->u.destroydomain.force;
- ret = (dom == IDLE_DOMAIN_ID) ? -EPERM : kill_other_domain(dom, force);
+ ret = kill_other_domain(dom, force);
}
break;
unsigned long warpl = op->u.adjustdom.warpl;
unsigned long warpu = op->u.adjustdom.warpu;
- ret = -EPERM;
- if ( dom != IDLE_DOMAIN_ID )
- ret = sched_adjdom(dom, mcu_adv, warp, warpl, warpu);
+ ret = sched_adjdom(dom, mcu_adv, warp, warpl, warpu);
}
break;
case DOM0_GETDOMAININFO:
{
- struct task_struct *p = &idle0_task;
+ struct task_struct *p;
u_long flags;
int i;
read_lock_irqsave (&tasklist_lock, flags);
- while ( (p = p->next_task) != &idle0_task )
- if ( !is_idle_task(p) &&
- (p->domain >= op->u.getdomaininfo.domain) )
+ for_each_domain ( p )
+ {
+ if ( p->domain >= op->u.getdomaininfo.domain )
break;
+ }
- if ( p == &idle0_task )
+ if ( p == NULL )
{
ret = -ESRCH;
}
/* Both these structures are protected by the tasklist_lock. */
rwlock_t tasklist_lock __cacheline_aligned = RW_LOCK_UNLOCKED;
struct task_struct *task_hash[TASK_HASH_SIZE];
+struct task_struct *task_list;
struct task_struct *do_createdomain(domid_t dom_id, unsigned int cpu)
{
- int retval;
char buf[100];
- struct task_struct *p = NULL;
+ struct task_struct *p, **pp;
unsigned long flags;
- retval = -ENOMEM;
- p = alloc_task_struct();
- if ( p == NULL ) return NULL;
+ if ( (p = alloc_task_struct()) == NULL )
+ return NULL;
memset(p, 0, sizeof(*p));
atomic_set(&p->refcnt, 1);
p->domain = dom_id;
p->processor = cpu;
- /* We use a large intermediate to avoid overflow in sprintf. */
- sprintf(buf, "Domain-%llu", dom_id);
- strncpy(p->name, buf, MAX_DOMAIN_NAME);
- p->name[MAX_DOMAIN_NAME-1] = '\0';
-
- spin_lock_init(&p->blk_ring_lock);
- spin_lock_init(&p->event_channel_lock);
-
- p->shared_info = (void *)get_free_page(GFP_KERNEL);
- memset(p->shared_info, 0, PAGE_SIZE);
- SHARE_PFN_WITH_DOMAIN(virt_to_page(p->shared_info), p);
+ memcpy(&p->thread, &idle0_task.thread, sizeof(p->thread));
- p->mm.perdomain_pt = (l1_pgentry_t *)get_free_page(GFP_KERNEL);
- memset(p->mm.perdomain_pt, 0, PAGE_SIZE);
+ if ( p->domain != IDLE_DOMAIN_ID )
+ {
+ /* We use a large intermediate to avoid overflow in sprintf. */
+ sprintf(buf, "Domain-%llu", dom_id);
+ strncpy(p->name, buf, MAX_DOMAIN_NAME);
+ p->name[MAX_DOMAIN_NAME-1] = '\0';
- init_blkdev_info(p);
+ spin_lock_init(&p->blk_ring_lock);
+ spin_lock_init(&p->event_channel_lock);
+
+ p->addr_limit = USER_DS;
+
+ spin_lock_init(&p->page_list_lock);
+ INIT_LIST_HEAD(&p->page_list);
+ p->max_pages = p->tot_pages = 0;
- p->addr_limit = USER_DS;
+ p->shared_info = (void *)get_free_page(GFP_KERNEL);
+ memset(p->shared_info, 0, PAGE_SIZE);
+ SHARE_PFN_WITH_DOMAIN(virt_to_page(p->shared_info), p);
+
+ p->mm.perdomain_pt = (l1_pgentry_t *)get_free_page(GFP_KERNEL);
+ memset(p->mm.perdomain_pt, 0, PAGE_SIZE);
+
+ init_blkdev_info(p);
+
+ write_lock_irqsave(&tasklist_lock, flags);
+ pp = &task_list; /* NB. task_list is maintained in order of dom_id. */
+ for ( pp = &task_list; *pp != NULL; pp = &(*pp)->next_list )
+ if ( (*pp)->domain > p->domain )
+ break;
+ p->next_list = *pp;
+ *pp = p;
+ p->next_hash = task_hash[TASK_HASH(dom_id)];
+ task_hash[TASK_HASH(dom_id)] = p;
+ write_unlock_irqrestore(&tasklist_lock, flags);
+ }
+ else
+ {
+ sprintf(p->name, "Idle-%d", cpu);
+ }
sched_add_domain(p);
- spin_lock_init(&p->page_list_lock);
- INIT_LIST_HEAD(&p->page_list);
- p->max_pages = p->tot_pages = 0;
-
- write_lock_irqsave(&tasklist_lock, flags);
- SET_LINKS(p);
- p->next_hash = task_hash[TASK_HASH(dom_id)];
- task_hash[TASK_HASH(dom_id)] = p;
- write_unlock_irqrestore(&tasklist_lock, flags);
-
return p;
}
* holds a reference to the domain being queried. Take care!
*/
write_lock_irqsave(&tasklist_lock, flags);
- REMOVE_LINKS(p);
- pp = &task_hash[TASK_HASH(p->domain)];
- while ( *pp != p ) *pp = (*pp)->next_hash;
+ pp = &task_list; /* Delete from task_list. */
+ while ( *pp != p )
+ *pp = (*pp)->next_list;
+ *pp = p->next_list;
+ pp = &task_hash[TASK_HASH(p->domain)]; /* Delete from task_hash. */
+ while ( *pp != p )
+ *pp = (*pp)->next_hash;
*pp = p->next_hash;
write_unlock_irqrestore(&tasklist_lock, flags);
read_lock_irqsave(&tasklist_lock, flags);
- p = &idle0_task;
- do {
+ for_each_domain ( p )
+ {
printk("Xen: DOM %llu, CPU %d [has=%c], state = %s, "
"hyp_events = %08x\n",
p->domain, p->processor, p->has_cpu ? 'T':'F',
task_states[p->state], p->hyp_events);
s = p->shared_info;
- if( !is_idle_task(p) )
- {
- printk("Guest: events = %08lx, events_mask = %08lx\n",
- s->events, s->events_mask);
- printk("Notifying guest...\n");
- cpu_mask |= mark_guest_event(p, _EVENT_DEBUG);
- }
- } while ( (p = p->next_task) != &idle0_task );
+ printk("Guest: events = %08lx, events_mask = %08lx\n",
+ s->events, s->events_mask);
+ printk("Notifying guest...\n");
+ cpu_mask |= mark_guest_event(p, _EVENT_DEBUG);
+ }
read_unlock_irqrestore(&tasklist_lock, flags);
{
u_long t_flags;
write_lock_irqsave(&tasklist_lock, t_flags);
- p = &idle0_task;
- do {
- if ( (p->processor == cpu) && !is_idle_task(p) )
+ for_each_domain ( p )
+ {
+ if ( p->processor == cpu )
{
p->evt -= 0xe0000000;
p->avt -= 0xe0000000;
}
}
- while ( (p = p->next_task) != &idle0_task );
write_unlock_irqrestore(&tasklist_lock, t_flags);
schedule_data[cpu].svt -= 0xe0000000;
}
NR_PENDING_REQS, pending_prod, pending_cons);
read_lock_irqsave(&tasklist_lock, flags);
- p = &idle0_task;
- do {
- if ( !is_idle_task(p) )
- {
- printk("Domain: %llu\n", p->domain);
- blk_ring = p->blk_ring_base;
-
- printk(" req_prod:0x%08x, req_cons:0x%08x resp_prod:0x%08x/"
- "0x%08x on_list=%d\n",
- blk_ring->req_prod, p->blk_req_cons,
- blk_ring->resp_prod, p->blk_resp_prod,
- __on_blkdev_list(p));
- }
- p = p->next_task;
- }
- while ( (p = p->next_task) != &idle0_task );
+ for_each_domain ( p )
+ {
+ printk("Domain: %llu\n", p->domain);
+ blk_ring = p->blk_ring_base;
+ printk(" req_prod:0x%08x, req_cons:0x%08x resp_prod:0x%08x/"
+ "0x%08x on_list=%d\n",
+ blk_ring->req_prod, p->blk_req_cons,
+ blk_ring->resp_prod, p->blk_resp_prod,
+ __on_blkdev_list(p));
+ }
read_unlock_irqrestore(&tasklist_lock, flags);
for ( i = 0; i < MAX_PENDING_REQS; i++ )
if ( probe->domain == VBD_PROBE_ALL )
{
read_lock_irqsave(&tasklist_lock, flags);
- p = &idle0_task;
- while ( (p = p->next_task) != &idle0_task )
+ for_each_domain ( p )
{
- if ( !is_idle_task(p) )
+ if ( (ret = vbd_probe_devices(&probe->xdi, p)) != 0 )
{
- if( (ret = vbd_probe_devices(&probe->xdi, p)) != 0 )
- {
- read_unlock_irqrestore(&tasklist_lock, flags);
- goto out;
- }
+ read_unlock_irqrestore(&tasklist_lock, flags);
+ goto out;
}
}
read_unlock_irqrestore(&tasklist_lock, flags);
char name[MAX_DOMAIN_NAME];
struct thread_struct thread;
- struct task_struct *prev_task, *next_task, *next_hash;
-
+ struct task_struct *next_list, *next_hash;
+
/* Event channel information. */
event_channel_t *event_channel;
unsigned int max_event_channel;
mm: IDLE0_MM, \
addr_limit: KERNEL_DS, \
thread: INIT_THREAD, \
- prev_task: &(_t), \
- next_task: &(_t), \
flags: 1<<PF_IDLETASK \
}
void continue_nonidle_task(void);
-/* This hash table is protected by the tasklist_lock. */
+/* This task_hash and task_list are protected by the tasklist_lock. */
#define TASK_HASH_SIZE 256
#define TASK_HASH(_id) ((int)(_id)&(TASK_HASH_SIZE-1))
extern struct task_struct *task_hash[TASK_HASH_SIZE];
+extern struct task_struct *task_list;
-#define REMOVE_LINKS(p) do { \
- (p)->next_task->prev_task = (p)->prev_task; \
- (p)->prev_task->next_task = (p)->next_task; \
- } while (0)
-
-#define SET_LINKS(p) do { \
- (p)->next_task = &idle0_task; \
- (p)->prev_task = idle0_task.prev_task; \
- idle0_task.prev_task->next_task = (p); \
- idle0_task.prev_task = (p); \
- } while (0)
+#define for_each_domain(_p) \
+ for ( (_p) = task_list; (_p) != NULL; (_p) = (_p)->next_list )
extern void update_process_times(int user);